#----------------------------------------------------------------------------
# wxPita - wxPython wrapper library for painless layout and event binding
#
# Author:       Feihong Hsu
# Email:        hsu DOT feihong AT yahoo DOT com
# Website:      http://wxpita.googlecode.com/
# Created:      2007 Dec 15
# Copyright:    (c) 2007 by Feihong Hsu
# License:      BSD License
#----------------------------------------------------------------------------
import wx
from peak.events import trellis
import core

mappings = {}

def add_value_widgets(text):
    for wname, ename in get_map_items(text):
        add_widget(wname, ename, True)

def add_selection_widgets(text):
    for wname, ename in get_map_items(text):
        add_widget(wname, ename, False)
        
def add_widget(wname, ename, is_value_widget):
    widget_class = getattr(wx, wname)
    evtbinder = getattr(wx, ename)
    mappings[widget_class] = (evtbinder, is_value_widget)
    
def get_map_items(text):
    return (line.strip().split() for line in text.split('\n') if line.strip())

add_value_widgets("""
    TextCtrl        EVT_TEXT
    ComboBox        EVT_TEXT
    SpinCtrl        EVT_SPIN
    DatePickerCtrl  EVT_DATE_CHANGED
    CheckBox        EVT_CHECKBOX
    Slider          EVT_SCROLL_CHANGED
""")

add_selection_widgets("""
    ListBox         EVT_LISTBOX
    CheckListBox    EVT_CHECKLISTBOX
    Choice          EVT_CHOICE
    RadioBox        EVT_RADIOBOX
""")

def value_m2v(value, view):
    view.SetValue(value)

def value_v2m(view, model, member):
    setattr(model, member, view.GetValue())

def selection_m2v(index, view):
    view.SetSelection(index)

def selection_v2m(view, model, member):
    setattr(model, member, view.GetSelection())

def selections_m2v(indexes, view):
    for i in view.GetSelections():
        view.Deselect(i)
    for i in indexes:
        view.SetSelection(i)

def selections_v2m(view, model, member):
    setattr(model, member, view.GetSelections())
    
class Controller(trellis.Component):
    model = trellis.value(None)
    cell = trellis.value(None)

    view = None
    member = ''
    evtbinder = None
    m2v = None
    v2m = None

    @trellis.action
    def init(self):
        self.cell = trellis.Cells(self.model)[self.member]
        # Binding this object to the view as an event handler ensures it
        # won't be deleted until the view itself is deleted
        self.view.Bind(self.evtbinder, self)

    @trellis.action
    def update_view(self):
        self.m2v(self.cell, self.view)

    def __call__(self, evt):
        "I am an event handler"
        self.v2m(self.view, self.model, self.member)

def DataBind(model, view, members):
    members = [m.strip() for m in members.split(',')]

    for member in members:
        name, ismulti = (member.split(':')[0], True) if ':' in member \
                        else (member, False)

        if isinstance(view, core.WxWrapper):
            view = view.widget
        memberwidget = getattr(view, name)
        evtbinder, is_value_widget = mappings[memberwidget.__class__]


        if is_value_widget:
            m2v, v2m = value_m2v, value_v2m
        elif ismulti:
            m2v, v2m = selections_m2v, selections_v2m
        else:
            m2v, v2m = selection_m2v, selection_v2m
        
        Controller(model=model, member=name, view=memberwidget,
                   evtbinder=evtbinder, m2v=m2v, v2m=v2m)
